package br.com.busgps.crawler;

import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.net.MalformedURLException;
import java.net.SocketTimeoutException;
import java.net.URL;
import java.text.MessageFormat;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.jsoup.Jsoup;
import org.jsoup.nodes.Document;
import org.jsoup.nodes.Element;
import org.jsoup.select.Elements;
import org.quartz.Job;
import org.quartz.JobExecutionContext;
import org.quartz.JobExecutionException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import au.com.bytecode.opencsv.CSVReader;
import br.com.busgps.util.Constants;

/**
 *
 * <b>Descricao da Classe:</b><br>
 * 
 * Job responsavel por obter o percurso de cada linha de onibus.
 *
 * @author rodrigo.bacellar
 * @since 07/11/2014
 *
 */
public class CrawlerBusRoute implements Job
{

    private static Logger logger = LoggerFactory.getLogger(CrawlerBusRoute.class);

    private static String DATE_PATTERN = "yyyy-MM-dd";

    
    public void execute(JobExecutionContext arg0) throws JobExecutionException
    {
        /**
         * TODO VERIFICAR SE EXISTE ALGUMA LINHA QUE NAO ESTA NO BANCO.
         * SE NAO TIVER, INSERIR NO BANCO E INCLUIR SEU RESPECTIVO PERCUSO.
         * SE TIVER, COMPARAR COM O PERCURSO QUE EXISTE NO BANCO PRA SABER SE HA NECESSIDADE DE ATUALIZAR.
         */

        Map<String, List<String[]>> routes = new HashMap<String, List<String[]>>();
        
        /** Armazena as linhas de onibus que deram algum problema para tentar novamente. */
        List<String> refazer = new ArrayList<String>();
        
        try
        {

            Elements links = getElements(Constants.REQUEST_LINES_URL,Constants.HTML_RESOURCE_LINK_TAG_PATTERN);

            for (Element link : links)
            {
                /** Numero do onibus */
                String linha = link.attr("title").split(" ")[3];
                
                try
                {
                    List<String[]> route = getRoute(linha);
                    
                    routes.put(linha, route);
                }
                catch (MalformedURLException e)
                {
                    refazer.add(linha);
                }
                catch (IOException e)
                {
                    refazer.add(linha);
                }
                catch (Exception e)
                {
                    refazer.add(linha);
                }
            }
        }
        catch (SocketTimeoutException e)
        {
            e.printStackTrace();
        }
        catch (IOException e)
        {
            e.printStackTrace();
        }
        catch (Exception e)
        {
            e.printStackTrace();
        }
    }

    
    /**
     * 
     * Metodo que obtem o percurso dada um linha de onibus.
     * 
     * @param linha
     * @return
     * @throws MalformedURLException
     * @throws IOException
     */
    private static List<String[]> getRoute(String linha) throws MalformedURLException, IOException
    {
        String url = MessageFormat.format(Constants.REQUEST_ROUTE_URL, linha);
        
        logger.info("Buscando arquivo na URL [{}]", url);
        
        InputStream input = new URL(url).openStream();
        CSVReader reader = new CSVReader(new InputStreamReader(input, "UTF-8"));

        /**
         * 
         * EXEMPLO DE LINHA
         * 
         * Linha [377], Descricao [377-PAVUNA X PRACA XV (VIA COSTA BARROS) RAPIDO CIRCULAR], Agencia [Fetranspor], Sequencia [669], Shape_id [26409316], Latitude [-22.896], Longitude [-43.1918]
         * 
         * SO ESTAO SENDO APROVEITADAS AS COLUNAS "SEQUENCIA", "LATITUDE" E "LONGITUDE".
         * 
         */

        String[] nextLine;

        /** Descarta o cabecalho */
        reader.readNext();

        /** Variaveis para auxiliar a leitura do arquivo */
        int seqAntigo = -1;
        int seqProximo;
        boolean hasToCheck = true;
        
        List<String[]> busPath = new ArrayList<String[]>();
        
        String date = new SimpleDateFormat(DATE_PATTERN).format(new Date());
        
        while ((nextLine = reader.readNext()) != null)
        {
            seqProximo = Integer.parseInt(nextLine[3]);
            
            if(hasToCheck)
            {
                /**Compara se a sequencia para saber se eh IDA ou VOLTA*/
                if(seqAntigo < seqProximo)
                {
                    String[] line = { linha, nextLine[3], nextLine[5], nextLine[6], Constants.IDA, date };
                    busPath.add(line);
                }
                else
                {
                    String[] line = { linha, nextLine[3], nextLine[5], nextLine[6], Constants.VOLTA, date };
                    busPath.add(line);
                    hasToCheck = false;
                }
            }
            else
            {
                String[] line = { linha, nextLine[3], nextLine[5], nextLine[6], Constants.VOLTA, date };
                busPath.add(line);
            }
            
            seqAntigo = seqProximo;
        }
        input.close();

        return busPath;
    }

    
    /**
     * 
     * Metodo que obtem os elementos na pagina dado um padrao
     * 
     * @param url
     * @param pattern
     * @return
     * @throws IOException
     */
    private static Elements getElements(String url, String pattern) throws IOException
    {
        
        long startTime = System.currentTimeMillis();
        
        /** CRIA UMA CONEXAO E RECUPERA O HTML */
        Document doc = Jsoup.connect(url).timeout(10000).get();

        logger.info("Conexao estabelecida na URL [{}], Tempo[{}]", url, (System.currentTimeMillis()-startTime));
        
        /** VARRE O CODIGO FONTE E FAZ MATCH PELA TAG */
        return doc.select(pattern);
    }
    
    
    
    public static void main(String[] args) throws Exception
    {

        /** CRIA UMA CONEXAO E RECUPERA O HTML */
        Document doc = Jsoup.connect(Constants.REQUEST_LINES_URL).timeout(10000).get();

        /** VARRE O CODIGO FONTE E FAZ MATCH PELA TAG */
        Elements links = doc.select(Constants.HTML_RESOURCE_LINK_TAG_PATTERN);
        
        List<String[]> routes = getRoute(links.get(0).attr("title").split(" ")[3]);
        
        for(String[] route : routes)
        {
            System.out.println("[" + route[0] + "],[" + route[1] + "],[" + route[2] + "],[" + route[3] + "],[" + route[4] + "],[" + route[5] + "]");
        }
        
    }
}
